home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 5 / Gekikoh Dennoh Club Vol. 5 (Japan).7z / Gekikoh Dennoh Club Vol. 5 (Japan) (Track 01).bin / internet / webx / webcm011.lzh / WebCache / WebCache.c next >
C/C++ Source or Header  |  1998-09-27  |  11KB  |  477 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include "../FuncUrl/FuncUrl.h"
  6.  
  7. #ifdef WEBXPRESSION
  8. #include "../WebXpression.h"
  9. #endif
  10. #ifdef ROBOGET
  11. #include "../RoboGet.h"
  12. #endif
  13. #ifdef WEBCM
  14. #include "../WebCM.h"
  15. #endif
  16.  
  17. /* URL é╞âeâôâ|âëâèâtâ@âCâïû╝é╠æ╬ë₧ì\æóæ╠ */
  18. typedef struct _temptable {
  19.     struct _temptable *next;/* ò╨ò√îⁿâèâXâg */
  20.     char hash;        /* ânâbâVâàÆl */
  21.     char type;        /* Content-Type */
  22.     unsigned int number;    /* âeâôâ|âëâèâtâ@âCâïû╝üié╠ÉöÆlòöüj */
  23.     unsigned int length;    /* âtâ@âCâïâTâCâY */
  24.     short year;        /* 0...32767 */
  25.     char mon;        /* 1...12 */
  26.     char day;        /* 1...31 */
  27.     char hour;        /* 0...23 */
  28.     char min;        /* 0...59 */
  29.     char sec;        /* 0...59 */
  30.     char access;        /* âAâNâZâXâtâëâO */
  31.     char url[0];        /* urlüiGCC é╔ê╦æ╢é╡é╜ò\ïLé┼éáéΘé▒é╞é╔Æìê╙üj */
  32. } TEMPTABLE;
  33.  
  34.  
  35. static char *content_type_str[]=
  36. {"text/html", "text/plain", "text/plain",
  37.  "image/gif", "image/jpeg", "image/ping", "image/bmp",
  38.  "application/zip", "application/lzh", "application/gzip",
  39.  "application/pdf",
  40.  "application/octet-stream", "unknown/unknown"};
  41. static char *ext_type_str[]=
  42. {"HTM", "TXT", "DOC",
  43.  "GIF", "JPG", "PNG", "BMP",
  44.  "ZIP", "LZH", "TGZ",
  45.  "PDF",
  46.  "DAT", "DAT"};
  47.  
  48. /* WCExist é╠ò╘éΦÆl */
  49. enum {
  50.     WC_NON = 0,        /* âLâââbâVâàé╔æ╢ì▌é╡é╚éó */
  51.     WC_INCACHE,        /* üV    é╔æ╢ì▌é╡üAïNô«îπÅëé▀é─é╠âAâNâZâX */
  52.     WC_INCACHE2,        /* üV    é╔æ╢ì▌é╡üAïNô«îπéPë±ê╚ÅπâAâNâZâXé╡é─éóéΘ */
  53.     WC_LOCAL        /* âìü[âJâïâtâ@âCâïé╞é╡é─æ╢ì▌é╖éΘüifile:// Ä₧üj */
  54. };
  55.  
  56. TEMPTABLE *tt_top = NULL, *tt_end = NULL;
  57. unsigned int cache_sum = 0;    /* î╗ì▌âLâââbâVâàé╡é─éóéΘâtâ@âCâïÉö */
  58. unsigned int abs_max = 0;    /* Cxxxxxxx é╠ì┼æσÆl+1 */
  59. unsigned int abs_min = -1;    /* Cxxxxxxx é╠ì┼żÆl */
  60. char cachedir[256];        /* è┬ï½ò╧Éö WEBCACHE */
  61. char cache_changed;    /* âLâââbâVâàé╠ôαùeé≡éPë±é┼éαò╧ìXé╡é╜é⌐üH */
  62.  
  63.  
  64. /* url é⌐éτânâbâVâàÆlé≡ïüé▀éΘ */
  65. static char Url2Hash (char *url)
  66. {
  67.     char c = 0, t, *p = url;
  68.  
  69.     while (t = *p++) {
  70.         if ((t >= 'A') && (t <= 'Z'))
  71.             t |= 0x20;
  72.         c ^= t;
  73.     }
  74.  
  75.     return (c);
  76. }
  77.  
  78.  
  79. /* âmü[âhùpé╠âüâéâèé≡èmò█ */
  80. static TEMPTABLE *TTAlloc (char *url)
  81. {
  82.     return (malloc (sizeof (TEMPTABLE) + strlen (url) + 1));
  83. }
  84.  
  85.  
  86. /* âmü[âhé≡âèâXâgé╠ûûö÷é╔éPé┬Æ╟ë┴ */
  87. static void TTInsert (TEMPTABLE * tt)
  88. {
  89.     if (tt_end == NULL) {
  90.         /* âmü[âhé¬éPé┬éαé╚éóÅΩìç */
  91.         tt_top = tt;
  92.     } else {
  93.         tt_end->next = tt;
  94.     }
  95.     tt_end = tt;
  96.     tt->next = NULL;
  97.     cache_changed = !0;
  98. }
  99.  
  100.  
  101. /* âmü[âhé≡éPé┬ìφÅ£ */
  102. static void TTDelete (TEMPTABLE * tt, TEMPTABLE * tt_b)
  103. {
  104.     if (tt->next == NULL) {
  105.         if (tt == tt_top) {
  106.             /* éPé┬é╡é⌐é╚éóâmü[âhé≡ìφÅ£é╖éΘÅΩìç */
  107.             tt_top = NULL;
  108.             tt_end = NULL;
  109.         } else {
  110.             /* ûûö÷é╠âmü[âhé╠ÅΩìç */
  111.             tt_end = tt_b;
  112.             tt_end->next = NULL;
  113.         }
  114.     } else {
  115.         if (tt == tt_top) {
  116.             /* Éµô¬é╠âmü[âhé≡ìφÅ£é╖éΘÅΩìç */
  117.             tt_top = tt->next;
  118.         } else {
  119.             tt_b->next = tt->next;
  120.         }
  121.     }
  122.     free (tt);
  123.     cache_changed = !0;
  124. }
  125.  
  126.  
  127.  
  128. int WCInit (void)
  129. {
  130.     FILE *fp;
  131.     char *t;
  132.     char temp_str[1024];
  133.  
  134.     t = getenv ("WEBCACHE");
  135.     if (t)
  136.         strcpy (cachedir, t);
  137.     else
  138.         *cachedir = '\0';
  139.  
  140.     strcpy (temp_str, cachedir);
  141.     strcat (temp_str, "WebCache.env");
  142.     if ((fp = fopen (temp_str, "r")) != NULL) {
  143.         while (fgets (temp_str, 1024, fp) != NULL) {
  144.             int year, mon, day, hour, min, sec;
  145.             int number, length;
  146.             char url[256], ext[4], type[39];
  147.             TEMPTABLE *tt;
  148.             int i;
  149.  
  150.             sscanf (temp_str, "C%7d.%s %4d/%2d/%2d %2d:%2d:%2d %d %s %s\n",
  151.                 &number, ext, &year, &mon, &day, &hour, &min, &sec,
  152.                 &length, url, type);
  153.             if (tt = TTAlloc (url)) {
  154.                 TTInsert (tt);
  155.                 tt->hash = Url2Hash (url);
  156.                 tt->number = number;
  157.                 tt->length = length;
  158.                 tt->year = year;
  159.                 tt->mon = mon;
  160.                 tt->day = day;
  161.                 tt->hour = hour;
  162.                 tt->min = min;
  163.                 tt->sec = sec;
  164.                 tt->access = 0;
  165.                 for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
  166.                     if (!strcmp (type, content_type_str[i]))
  167.                         break;
  168.                 }
  169.                 tt->type = i;
  170.                 strcpy (tt->url, url);
  171.  
  172.                 if (number > abs_max)
  173.                     abs_max = number;
  174.                 if (number < abs_min)
  175.                     abs_min = number;
  176.                 cache_sum++;
  177.                 abs_max++;
  178.             }
  179.         }
  180.         fclose (fp);
  181.     } else {
  182.         if ((fp = fopen (temp_str, "w")) != NULL)
  183.             fclose (fp);
  184.     }
  185.     cache_changed = 0;
  186.     return (0);
  187. }
  188.  
  189.  
  190.  
  191. /* httpfile->url é┼ÄwÆΦé╡é╜âtâ@âCâïé¬âLâââbâVâàé╔æ╢ì▌é╖éΘé⌐ */
  192. /* æ╢ì▌é╖éΘé╚éτ httpfile é╔èeÄφÅεò±é╞ cache_fnameüiâtâïâpâXüjé¬ò╘éΘ */
  193. int WCExist (HTTPFILE * httpfile, char *cache_fname)
  194. {
  195.     TEMPTABLE *tt = tt_top;
  196.     char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
  197.     int port;
  198.     /* Éµô¬é╔ http:// é≡Æ╟ë┴üA'../'ôÖÅêù¥ì╧é▌üAanchor é≡ìφÅ£é╡é╜ URL */
  199.     char temp_url[256];
  200.     short h;
  201.     char *scheme_str[]=
  202.     {"http://", "file://"};
  203.  
  204.     /* âAâôâJü[é≡ìφÅ£é╡é─îƒì⌡ */
  205.     UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
  206.     UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
  207.  
  208.     /* scheme é╔éµé┴é─ò¬è≥ */
  209.     for (h = 0; h < sizeof (scheme_str) / sizeof (char *); h++) {
  210.         if (!strnicmp (temp_url, scheme_str[h], strlen (scheme_str[h])))
  211.             break;
  212.     }
  213.     switch (h) {
  214.     case 0:        /* http:// */
  215.         {
  216.             char hash;
  217.  
  218.             hash = Url2Hash (temp_url);
  219.             while (tt != NULL) {
  220.                 if (tt->hash == hash) {    /* é▄é╕ânâbâVâàÆlé┼ìéæ¼é╔îƒì⌡ */
  221.                     if (!stricmp (tt->url, temp_url)) {
  222.                         sprintf (cache_fname, "%sC%07d.%s", cachedir, tt->number, ext_type_str[tt->type]);
  223.                         strcpy (httpfile->content_type, content_type_str[tt->type]);
  224.                         httpfile->content_length = tt->length;
  225.                         (httpfile->time_stamp).tm_year = tt->year - 1900;
  226.                         (httpfile->time_stamp).tm_mon = tt->mon - 1;
  227.                         (httpfile->time_stamp).tm_mday = tt->day;
  228.                         (httpfile->time_stamp).tm_hour = tt->hour;
  229.                         (httpfile->time_stamp).tm_min = tt->min;
  230.                         (httpfile->time_stamp).tm_sec = tt->sec;
  231.                         /* ïNô«îπé╔âAâNâZâXé╡é╜é⌐üH */
  232.                         if (tt->access == 0) {
  233.                             return (WC_INCACHE);
  234.                         } else {
  235.                             return (WC_INCACHE2);
  236.                         }
  237.                     }
  238.                 }
  239.                 tt = tt->next;
  240.             }
  241.         }
  242.         break;
  243.     case 1:        /* file:// */
  244.     default:
  245.         {
  246.             FILE *fp;
  247.  
  248.             if (!strnicmp (httpfile->url, "file://", 7))
  249.                 strcpy (cache_fname, httpfile->url + 7);
  250.             else
  251.                 strcpy (cache_fname, httpfile->url);
  252.  
  253.             if ((fp = fopen (cache_fname, "rb")) != NULL) {
  254.                 int i;
  255.                 char c;
  256.                 char *p;
  257.                 char ext[256];
  258.  
  259.                 httpfile->content_length = filelength (fileno (fp));
  260.                 fclose (fp);
  261.  
  262.                 /* â}âïâ`âsâèâIâhö±æ╬ë₧üEüEüE */
  263.                 ext[0] = '\0';
  264.                 p = &httpfile->url[7];
  265.                 while (c = *p++) {
  266.                     if (c == '.') {
  267.                         strcpy (ext, p);
  268.                         break;
  269.                     }
  270.                 }
  271.                 for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
  272.                     if (!stricmp (ext, ext_type_str[i]))
  273.                         break;
  274.                 }
  275.                 strcpy (httpfile->content_type, content_type_str[i]);
  276.                 return (WC_LOCAL);
  277.             } else {
  278.                 *cache_fname = '\0';
  279.                 httpfile->content_length = 0;
  280.                 *httpfile->content_type = '\0';
  281.             }
  282.         }
  283.         break;
  284.     }
  285.     return (WC_NON);
  286. }
  287.  
  288.  
  289.  
  290. /* âAâNâZâXâtâëâOé≡âZâbâg */
  291. int WCSetAccess (HTTPFILE * httpfile)
  292. {
  293.     TEMPTABLE *tt = tt_top;
  294.     char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
  295.     int port;
  296.     /* Éµô¬é╔ http:// é≡Æ╟ë┴üA'../'ôÖÅêù¥ì╧é▌üAanchor é≡ìφÅ£é╡é╜ URL */
  297.     char temp_url[256];
  298.     char hash;
  299.  
  300.     /* âAâôâJü[é≡ìφÅ£é╡é─îƒì⌡ */
  301.     UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
  302.     UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
  303.  
  304.     if (strnicmp (temp_url, "http://", 7))
  305.         return (-1);    /* http:// é┼é╚é»éΩé╬ïAéΘ */
  306.  
  307.     hash = Url2Hash (temp_url);
  308.     while (tt != NULL) {
  309.         if (tt->hash == hash) {    /* é▄é╕ânâbâVâàÆlé┼ìéæ¼é╔îƒì⌡ */
  310.             if (!stricmp (tt->url, temp_url)) {
  311.                 tt->access = !0;
  312.                 return (0);
  313.             }
  314.         }
  315.         tt = tt->next;
  316.     }
  317.     return (0);
  318. }
  319.  
  320.  
  321.  
  322. /* httpfile->url é┼ÄwÆΦé╡é╜âtâ@âCâïé≡âLâââbâVâàé╔ôoÿ^é╖éΘ */
  323. /* cache_fnameüiâtâïâpâXüjé¬ò╘éΘ */
  324. int WCInsertUrl (HTTPFILE * httpfile, char *cache_fname)
  325. {
  326.     int i;
  327.     TEMPTABLE *tt;
  328.     char scheme[256], hostname[256], path[256], fname[256], query[256], anchor[256];
  329.     int port;
  330.     char temp_url[256];
  331.     short h;
  332.     char *scheme_str[]=
  333.     {"http://", "file://"};
  334.  
  335.     /* scheme é╔éµé┴é─ò¬è≥ */
  336.     for (h = 0; h < sizeof (scheme_str) / sizeof (char *); h++) {
  337.         if (!strnicmp (httpfile->url, scheme_str[h], strlen (scheme_str[h])))
  338.             break;
  339.     }
  340.     switch (h) {
  341.     case 0:        /* http:// */
  342.         for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
  343.             if (!strcmp (httpfile->content_type, content_type_str[i]))
  344.                 break;
  345.         }
  346.  
  347.         /* âLâââbâVâàé╔é═âAâôâJü[é≡ìφÅ£é╡é─ôoÿ^ */
  348.         UrlSplit (httpfile->url, scheme, hostname, path, fname, query, anchor, &port);
  349.         UrlCat (temp_url, scheme, hostname, path, fname, query, "", port);
  350.  
  351.         if ((tt = TTAlloc (httpfile->url)) == NULL)
  352.             return (-1);    /* âüâéâèòsæ½ */
  353.         TTInsert (tt);
  354.         tt->hash = Url2Hash (temp_url);
  355.         tt->type = i;
  356.         tt->number = abs_max;
  357.         tt->year = httpfile->time_stamp.tm_year + 1900;
  358.         tt->mon = httpfile->time_stamp.tm_mon + 1;
  359.         tt->day = httpfile->time_stamp.tm_mday;
  360.         tt->hour = httpfile->time_stamp.tm_hour;
  361.         tt->min = httpfile->time_stamp.tm_min;
  362.         tt->sec = httpfile->time_stamp.tm_sec;
  363.         tt->access = !0;
  364.         tt->length = httpfile->content_length;
  365.         strcpy (tt->url, temp_url);
  366.  
  367.         sprintf (cache_fname, "%sC%07d.%s", cachedir, tt->number, ext_type_str[tt->type]);
  368.         cache_sum++;
  369.         abs_max++;
  370.         break;
  371.     case 1:        /* file:// */
  372.     default:
  373.         /* file:// é╠ÅΩìçé═âLâââbâVâàé╔ôoÿ^é╣é╕ cache_fname é╛é»ò╘é╖ */
  374.         {
  375.             FILE *fp;
  376.             strcpy (cache_fname, httpfile->url + 7);
  377.  
  378.             if ((fp = fopen (cache_fname, "rb")) != NULL) {
  379.                 int i;
  380.                 char c;
  381.                 char *p;
  382.                 char ext[256];
  383.  
  384.                 fclose (fp);
  385.  
  386.                 /* â}âïâ`âsâèâIâhö±æ╬ë₧üEüEüE */
  387.                 ext[0] = '\0';
  388.                 p = &httpfile->url[7];
  389.                 while (c = *p++) {
  390.                     if (c == '.') {
  391.                         strcpy (ext, p);
  392.                         break;
  393.                     }
  394.                 }
  395.                 for (i = 0; i < sizeof (ext_type_str) / 4 - 1; i++) {
  396.                     if (!stricmp (ext, ext_type_str[i]))
  397.                         break;
  398.                 }
  399.                 strcpy (httpfile->content_type, content_type_str[i]);
  400.                 return (!0);
  401.             } else {
  402.                 *cache_fname = '\0';
  403.                 return (0);
  404.             }
  405.         }
  406.         break;
  407.     }
  408.     return (0);
  409. }
  410.  
  411.  
  412.  
  413. int WCDeleteUrl (char *url)
  414. {
  415.     int r = -1;
  416.     char h;
  417.     TEMPTABLE *tt = tt_top, *tt_b = NULL;
  418.  
  419.     h = Url2Hash (url);
  420.     while (tt != NULL) {
  421.         if (tt->hash == h) {
  422.             if (!stricmp (tt->url, url)) {
  423.                 TTDelete (tt, tt_b);
  424.                 r = 0;
  425.                 break;
  426.             }
  427.         }
  428.         tt_b = tt;    /* éPé┬æOé╠âmü[âh */
  429.         tt = tt->next;
  430.     }
  431.     return (r);
  432. }
  433.  
  434.  
  435.  
  436. int WCSave (void)
  437. {
  438.     FILE *fp;
  439.     char temp_fname[256];
  440.     TEMPTABLE *tt = tt_top;
  441.  
  442.     if (!cache_changed)    /* âLâââbâVâàôαùeé╔ò╧ìXé¬é╚éóÅΩìç */
  443.         return (0);
  444.  
  445.     /* WebCache.env é≡ìXÉV */
  446.     strcpy (temp_fname, cachedir);
  447.     strcat (temp_fname, "WebCache.env");
  448.     if ((fp = fopen (temp_fname, "w")) != NULL) {
  449.         while (tt != NULL) {
  450.             int year, mon, day, hour, min, sec;
  451.             year = tt->year;
  452.             mon = tt->mon;
  453.             day = tt->day;
  454.             hour = tt->hour;
  455.             min = tt->min;
  456.             sec = tt->sec;
  457.  
  458.             fprintf (fp, "C%07d.%s %04d/%02d/%02d %02d:%02d:%02d %d\t%s\t%s\n",
  459.                  tt->number, ext_type_str[tt->type],
  460.                  year, mon, day, hour, min, sec,
  461.                  tt->length, tt->url, content_type_str[tt->type]);
  462.             tt = tt->next;
  463.         }
  464.         fclose (fp);
  465.     } else {
  466.         return (-1);
  467.     }
  468.     return (0);
  469. }
  470.  
  471.  
  472.  
  473. int WCTini (void)
  474. {
  475.     return (WCSave ());
  476. }
  477.